Merge pull request #65 from rishabhjain/TravelAgent

Travel Agent

Andrew Cantino 11 years ago
parent
commit
8005e7e2e8

+ 68 - 0
app/models/agents/adioso_agent.rb

@@ -0,0 +1,68 @@
1
+module Agents
2
+  class AdiosoAgent < Agent
3
+
4
+  cannot_receive_events!
5
+
6
+	default_schedule "every_1d"
7
+
8
+  description <<-MD
9
+		Adioso Agent will tell you about the minimum airline prices between a pair of cities, and between a certain period of time.
10
+    Currency is USD, Please make sure difference between `start_date` and `end_date` is less than 150 days. You will need to contact [Adioso](http://adioso.com/)
11
+		for `username` and `password`.
12
+  MD
13
+
14
+  event_description <<-MD
15
+
16
+    If flights are present then events look like:
17
+			{ "cost" : 75.23,
18
+        "date" : "June 25, 2013",
19
+			  "route" : "New York to Chicago" }
20
+
21
+    otherwise
22
+     { "nonetodest" : "No flights found to the specified destination" }
23
+  MD
24
+
25
+    def default_options
26
+      {
27
+        :start_date => Date.today.httpdate[0..15],
28
+        :end_date   => Date.today.plus_with_duration(100).httpdate[0..15],
29
+        :from       => "New York",
30
+        :to         => "Chicago",
31
+        :username   => "xx",
32
+        :password   => "xx",
33
+				:expected_update_period_in_days => "1"
34
+      }
35
+    end
36
+
37
+    def working?
38
+      (event = event_created_within(options[:expected_update_period_in_days].to_i.days)) && event.payload.present?
39
+    end
40
+
41
+    def validate_options
42
+			unless %w[start_date end_date from to username password expected_update_period_in_days].all? { |field| options[field.to_sym].present? }
43
+				errors.add(:base, "All fields are required")
44
+			end
45
+		end
46
+
47
+    def date_to_unix_epoch(date)
48
+      date.to_time.to_i
49
+    end
50
+
51
+    def check
52
+      auth_options = {:basic_auth => {:username =>options[:username], :password=>options[:password]}}
53
+      parse_response = HTTParty.get "http://api.adioso.com/v2/search/parse?q=#{URI.encode(options[:from])}+to+#{URI.encode(options[:to])}", auth_options
54
+      fare_request = parse_response["search_url"].gsub /(end=)(\d*)([^\d]*)(\d*)/, "\\1#{date_to_unix_epoch(options[:end_date])}\\3#{date_to_unix_epoch(options[:start_date])}"
55
+      fare = HTTParty.get fare_request, auth_options
56
+			unless fare["warnings"]
57
+				event = fare["results"].min {|a,b| a["cost"] <=> b["cost"]}
58
+				event["date"]  = Time.at(event["date"]).to_date.httpdate[0..15]
59
+				event["route"] = "#{options[:from]} to #{options[:to]}" 
60
+				create_event :payload => event
61
+			else
62
+				create_event :payload => fare["warnings"]
63
+			end
64
+				
65
+    end
66
+  end
67
+end
68
+

+ 196 - 0
spec/data_fixtures/adioso_fare.json

@@ -0,0 +1,196 @@
1
+{
2
+    "currency": "USD", 
3
+    "results": [
4
+        {
5
+            "cost": 431.74000000000001, 
6
+            "date": 1372032000, 
7
+            "route": [
8
+                "PDX", 
9
+                "DFW", 
10
+                "ORD"
11
+            ]
12
+        }, 
13
+        {
14
+            "cost": 431.74000000000001, 
15
+            "date": 1372118400, 
16
+            "route": [
17
+                "PDX", 
18
+                "DFW", 
19
+                "ORD"
20
+            ]
21
+        }, 
22
+        {
23
+            "cost": 341.72000000000003, 
24
+            "date": 1372204800, 
25
+            "route": [
26
+                "PDX", 
27
+                "LAS", 
28
+                "ORD"
29
+            ]
30
+        }, 
31
+        {
32
+            "cost": 625.57000000000005, 
33
+            "date": 1372291200, 
34
+            "route": [
35
+                "PDX", 
36
+                "LAX", 
37
+                "ORD"
38
+            ]
39
+        }, 
40
+        {
41
+            "cost": 348.14999999999998, 
42
+            "date": 1372377600, 
43
+            "route": [
44
+                "PDX", 
45
+                "LAS", 
46
+                "ORD"
47
+            ]
48
+        }, 
49
+        {
50
+            "cost": 306.81, 
51
+            "date": 1372464000, 
52
+            "route": [
53
+                "PDX", 
54
+                "LAS", 
55
+                "ORD"
56
+            ]
57
+        }, 
58
+        {
59
+            "cost": 307.73000000000002, 
60
+            "date": 1372550400, 
61
+            "route": [
62
+                "PDX", 
63
+                "LAS", 
64
+                "ORD"
65
+            ]
66
+        }, 
67
+        {
68
+            "cost": 257.20999999999998, 
69
+            "date": 1372636800, 
70
+            "route": [
71
+                "PDX", 
72
+                "DFW", 
73
+                "ORD"
74
+            ]
75
+        }, 
76
+        {
77
+            "cost": 245.27000000000001, 
78
+            "date": 1372723200, 
79
+            "route": [
80
+                "PDX", 
81
+                "LAS", 
82
+                "ORD"
83
+            ]
84
+        }, 
85
+        {
86
+            "cost": 293.02999999999997, 
87
+            "date": 1372809600, 
88
+            "route": [
89
+                "PDX", 
90
+                "LAS", 
91
+                "ORD"
92
+            ]
93
+        }, 
94
+        {
95
+            "cost": 194.74000000000001, 
96
+            "date": 1372896000, 
97
+            "route": [
98
+                "PDX", 
99
+                "LAS", 
100
+                "ORD"
101
+            ]
102
+        }, 
103
+        {
104
+            "cost": 244.34999999999999, 
105
+            "date": 1372982400, 
106
+            "route": [
107
+                "PDX", 
108
+                "LAS", 
109
+                "ORD"
110
+            ]
111
+        }, 
112
+        {
113
+            "cost": 305.88999999999999, 
114
+            "date": 1373068800, 
115
+            "route": [
116
+                "PDX", 
117
+                "LAS", 
118
+                "ORD"
119
+            ]
120
+        }, 
121
+        {
122
+            "cost": 306.81, 
123
+            "date": 1373155200, 
124
+            "route": [
125
+                "PDX", 
126
+                "LAS", 
127
+                "ORD"
128
+            ]
129
+        }, 
130
+        {
131
+            "cost": 248.94, 
132
+            "date": 1373241600, 
133
+            "route": [
134
+                "PDX", 
135
+                "LAS", 
136
+                "ORD"
137
+            ]
138
+        }, 
139
+        {
140
+            "cost": 244.34999999999999, 
141
+            "date": 1373328000, 
142
+            "route": [
143
+                "PDX", 
144
+                "LAS", 
145
+                "ORD"
146
+            ]
147
+        }, 
148
+        {
149
+            "cost": 245.27000000000001, 
150
+            "date": 1373414400, 
151
+            "route": [
152
+                "PDX", 
153
+                "LAS", 
154
+                "ORD"
155
+            ]
156
+        }, 
157
+        {
158
+            "cost": 277.42000000000002, 
159
+            "date": 1373500800, 
160
+            "route": [
161
+                "PDX", 
162
+                "DFW", 
163
+                "ORD"
164
+            ]
165
+        }, 
166
+        {
167
+            "cost": 297.63, 
168
+            "date": 1373587200, 
169
+            "route": [
170
+                "PDX", 
171
+                "LAS", 
172
+                "ORD"
173
+            ]
174
+        }, 
175
+        {
176
+            "cost": 209.44, 
177
+            "date": 1373673600, 
178
+            "route": [
179
+                "PDX", 
180
+                "LAS", 
181
+                "ORD"
182
+            ]
183
+        }, 
184
+        {
185
+            "cost": 259.95999999999998, 
186
+            "date": 1373760000, 
187
+            "route": [
188
+                "PDX", 
189
+                "LAS", 
190
+                "ORD"
191
+            ]
192
+        }
193
+    ], 
194
+    "type": "calendar", 
195
+    "warnings": null
196
+}

+ 19 - 0
spec/data_fixtures/adioso_parse.json

@@ -0,0 +1,19 @@
1
+{
2
+    "cost_max": null, 
3
+    "currency": "USD", 
4
+    "date_end": 1403740799, 
5
+    "date_start": 1372032000, 
6
+    "dest_codes": [
7
+        "CGX", 
8
+        "MDW", 
9
+        "ORD", 
10
+        "GYY"
11
+    ], 
12
+    "duration_max": null, 
13
+    "origin_codes": [
14
+        "PDX", 
15
+        "SLE"
16
+    ], 
17
+    "search_url": "http://api.adioso.com/v2/search/fares?currency=USD&date_end=1403740799&date_start=1372032000&dest_codes=CGX%2CMDW%2CORD%2CGYY&origin_codes=PDX%2CSLE", 
18
+    "segments_max": null
19
+}

+ 38 - 0
spec/models/agents/adioso_agent_spec.rb

@@ -0,0 +1,38 @@
1
+require 'spec_helper'
2
+
3
+describe Agents::AdiosoAgent do
4
+	before do
5
+		stub_request(:get, /parse/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/adioso_parse.json")), :status => 200, :headers => {"Content-Type" => "text/json"})
6
+		stub_request(:get, /fares/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/adioso_fare.json")),  :status => 200, :headers => {"Content-Type" => "text/json"})
7
+		@valid_params = {
8
+											:start_date => "June 25 2013",
9
+											:end_date   => "July 15 2013",
10
+											:from       => "Portland",
11
+											:to         => "Chicago",
12
+											:username   => "xx",
13
+											:password   => "xx",
14
+											:expected_update_period_in_days => "2"
15
+										}
16
+
17
+		@checker = Agents::AdiosoAgent.new(:name => "somename", :options => @valid_params)
18
+		@checker.user = users(:jane)
19
+		@checker.save!
20
+	end
21
+
22
+	describe "#check" do
23
+		it "should check that initial run creates an event" do
24
+			expect { @checker.check }.to change { Event.count }.by(1)
25
+		end
26
+	end
27
+
28
+	describe "#working?" do
29
+		it "checks if its generating events as scheduled" do
30
+			@checker.should_not be_working
31
+			@checker.check
32
+			@checker.should be_working
33
+			three_days_from_now = 3.days.from_now
34
+			stub(Time).now { three_days_from_now }
35
+			@checker.should_not be_working
36
+		end
37
+	end
38
+end